import javax.microedition.lcdui.*;

import resources.FontManager;
import resources.GraphicManager;

import java.util.*;

import localization.Language;
import localization.LocalizationManager;

public class ViewerScreen extends Canvas
{
	private final static Language language = LocalizationManager.getCurrentLanguageFromInstance();
	
    private TimeTable m_table;
    private int m_actual;                 //index aktualnie pokazywanego pola w planie
    private boolean m_showComment = false;//wskaznik czy wyswietlac komentarze    
    
    private final int BLOCK_HEIGHT = 28;            //wysokosc bloku ustawiona na sztywno - zalezy od wysokosci czcionki etc.
    private final int BLOCK_WIDTH = getWidth();     //szerokosc bloku = szerokosc ekranu
    //wyliczona ilosc blokow ktore sie zmieszcza na ekranie
    private final int BLOCK_COUNT = Math.min((getHeight()- getCaptionHeight())/BLOCK_HEIGHT, TimeTable.DAY_LESSONS );

    static public final Command m_edit = new Command( language.getEditText(), Command.SCREEN, 0);
    static public final Command m_delete=new Command( language.getDeleteText(), Command.SCREEN, 1);
    static public final Command m_back = new Command( language.getBackText(), Command.BACK, 0 );
            
	public ViewerScreen( TimeTable table, Scheduler midlet )
	{
        if( BLOCK_COUNT <= 0 ) throw new RuntimeException( language.getTooSmallDisplayText() ); //sprawdzenie ekranu 
        m_table= table;
        
        Calendar now = Calendar.getInstance(); 
        now.setTime( new Date() );               //dokladna aktualna data
        
        Calendar nowHour = Calendar.getInstance();
        nowHour.setTime( new Date( 0 ));
        nowHour.set( Calendar.HOUR_OF_DAY, now.get( Calendar.HOUR_OF_DAY ) );
        nowHour.set( Calendar.MINUTE, now.get( Calendar.MINUTE ) ); //tylko i wylacznie dzisiejsza godzina

        //ustawinie okna na aktualne zajecie lub poczatek dnia
        
        //ustawianie dnia tygodnia (kolumny)
        m_actual = (now.get( Calendar.DAY_OF_WEEK ) -2) * TimeTable.DAY_LESSONS; //-2 zeby zaczac od 0 i bez niedzieli 
        
        //jesli wyzszy dzien niz mamy wielkosc tabelki to ustawiamy na 0
        if( m_actual >= TimeTable.WEEK_DAYS * TimeTable.DAY_LESSONS || m_actual < 0 ) m_actual= 0; //jesli sobota - wyszlismy poza tabele, niedziela jest 1 dniem tygodnia!
        else
        {       
            //ustawienie lekcji na aktualna (lub na 1 okienko jak sie skonczyly)
            int i=m_actual;
            while( i<m_actual + TimeTable.DAY_LESSONS && ( !m_table.IsSet( i ) || m_table.GetEnd( i ).getTime() < nowHour.getTime().getTime() ) )
            {
                i++;
            }
            if( i< m_actual + TimeTable.DAY_LESSONS ) m_actual = i;
        }
    
        
        
        //dodanie komend do menu oraz ustawienie Listenera na Schedulera
        addCommand( m_edit );
        addCommand( m_delete );
        addCommand( m_back );
        setCommandListener( midlet );
	}
	
    protected void paint( Graphics g )
	{
        g.setColor(0xFFFFFF); 
        g.fillRect(0, 0, 200, 200); //biale tlo
        g.setColor(0x000000);

        g.drawImage( CreateCaption(), 0, 0, Graphics.TOP | Graphics.LEFT ); //umieszcza naglowek w lewym gornym rogu
        
        //jesli do 2 blokow na ekranie to aktualny wyswietlany jako pierwszy na gorze
        if( BLOCK_COUNT <= 2)
        {
            int startBlock;
            if( m_actual % TimeTable.DAY_LESSONS + 1 + BLOCK_COUNT - 1 > TimeTable.DAY_LESSONS ) startBlock= m_actual - (BLOCK_COUNT - 1);
            else startBlock= m_actual;
            
            for( int i=0; i< BLOCK_COUNT; i++)
            {
                g.drawImage(CreateBlock(startBlock+i),0, getCaptionHeight() + (i*BLOCK_HEIGHT), Graphics.TOP | Graphics.LEFT );
            }
        }
        else  //jesli ponad 2 bloki sie mieszcza to aktualny jako 2 na ekranie
        {
            int startBlock; 
            // ile blokow wychodzi poza dany dzien przy jednym aktualnym i jednym poprzednim
            int overCount = m_actual % TimeTable.DAY_LESSONS + 1 + BLOCK_COUNT - 2;
            // ile blokow wychodzi ponizej dane dzien przy jednym aktualnym i jednym poprzednim
            int underCount = m_actual % TimeTable.DAY_LESSONS - 1; 
            
            startBlock= m_actual - 1;
            if( underCount < 0 ) startBlock= m_actual;
            if( overCount > TimeTable.DAY_LESSONS ) startBlock= m_actual - (overCount - TimeTable.DAY_LESSONS ) - 1; // -1 dla poprzedniego jednego
            
            for( int i=0; i< BLOCK_COUNT; i++)
            {
                g.drawImage(CreateBlock(startBlock+i),0, getCaptionHeight() + (i*BLOCK_HEIGHT), Graphics.TOP | Graphics.LEFT );
            }
            
        }
    }
    
    public int GetActual()
    {
        return m_actual;
    }
    
    //oblsuga nacisniec klawiszy
    public void keyPressed( int keyCode )
    {
        int gameAction= getGameAction( keyCode );
        switch( gameAction )
        {
        case UP:   ChangeLesson( -1 ); break;
        case DOWN: ChangeLesson( 1 ); break;
        case LEFT: ChangeDay( -1 ); break;
        case RIGHT:ChangeDay( 1 ); break;
        }
        
        if( keyCode == KEY_STAR ) m_showComment= true;
        repaint();
    }
    
    public void keyReleased( int keyCode )
    {
        if( keyCode == KEY_STAR ) m_showComment= false;
        repaint();
    }
    
    private void ChangeDay( int count )
    {
        m_actual+= TimeTable.DAY_LESSONS * (TimeTable.WEEK_DAYS + count);
        m_actual %= (TimeTable.DAY_LESSONS * TimeTable.WEEK_DAYS);
    }
    
    private void ChangeLesson( int count )
    {
        int changed= (m_actual % TimeTable.DAY_LESSONS) + count;
        if( changed >= 0 && changed< TimeTable.DAY_LESSONS ) m_actual+= count;
    }
    
    
    
    private Image CreateBlock( int no )
    {        

        Image returnIm= Image.createImage( BLOCK_WIDTH, BLOCK_HEIGHT  );  // tyle zajmuje wysokosc bloku (3 linijki)
        Graphics g= returnIm.getGraphics();
        
        if( !m_table.IsSet(no))                                      //jesli nic nie ma to zwraca szary kwadrat
        {
            g.setColor( 0xD4D0C8);
            g.fillRect(0,0,BLOCK_WIDTH-1, BLOCK_HEIGHT-1);
            g.setColor( 0x000000);
        }
        else                                                         //rysowanie jesli pole ustawione
        {
            String hours = "";                             //przetwarzanie godzin startu i konca na string
            Calendar godzina = Calendar.getInstance();
            
            godzina.setTime( m_table.GetStart(no) );        
            hours += godzina.get( Calendar.HOUR_OF_DAY ) + ":";
            if( + godzina.get( Calendar.MINUTE )<10 ) hours+= "0";  //jesli minuty jednocyfrowe to dodaj 0
            hours += + godzina.get( Calendar.MINUTE ); 
            
            hours+= "-";
            
            godzina.setTime( m_table.GetEnd(no) );
            hours += godzina.get( Calendar.HOUR_OF_DAY ) + ":"; 
            if( godzina.get( Calendar.MINUTE )<10 ) hours+= "0";    //jesli minuty jednocyfrowe to dodaj 0
            hours+= godzina.get( Calendar.MINUTE );
            
            g.drawImage( getFonts().String2Image( hours ), 2,3, Graphics.TOP | Graphics.LEFT );
            g.drawImage( getFonts().String2Image(m_table.GetRoom(no)), BLOCK_WIDTH-4, 3 , Graphics.TOP | Graphics.RIGHT );
            
            //klawisz do pokazywanie komentarzy nie jest wcisniety lub nie ma komentarza
            if( !m_showComment || m_table.GetComment(no).length() <= 0 )   
            {
                g.drawImage( getFonts().String2Image(m_table.GetLesson(no)), BLOCK_WIDTH/2, 15, Graphics.TOP | Graphics.HCENTER );
                if( m_table.GetComment(no).length() > 0 )
                    g.drawImage( getCommentSign(), BLOCK_WIDTH-4, BLOCK_HEIGHT-3,Graphics.BOTTOM | Graphics.RIGHT );
            }
            else                   //klawisz do pokazywania komentarzy jest wcisniety
            {
                g.drawImage( getFonts().String2Image(m_table.GetComment(no)), BLOCK_WIDTH-3, 15, Graphics.TOP | Graphics.RIGHT );
            }
        } //koniec wypisywania jesli pole ustawione - nastepne rzeczy wszystekie pola

        if( m_actual == no)                            //podswietlenie aktualnego pola
        {
            g.setColor(0xFF0000);
            g.drawRect(1,1, BLOCK_WIDTH-3, BLOCK_HEIGHT-3);
            g.setColor(0x000000);
        }
        g.drawRect(0,0, BLOCK_WIDTH-1, BLOCK_HEIGHT-1);    // ramka dookola pola        
        
        
        return Image.createImage(returnIm);
    }
    
    private Image CreateCaption( )
    {
        Image returnIm= Image.createImage(BLOCK_WIDTH, getCaptionHeight() );
        Graphics g= returnIm.getGraphics();
        
      
        Image weekDay= null;
        
        switch( m_actual / TimeTable.DAY_LESSONS )
        {
        case 0: weekDay= getFonts().String2Image( language.getMondayText()); break;
        case 1: weekDay= getFonts().String2Image( language.getTuesdayText()); break;
        case 2: weekDay= getFonts().String2Image( language.getWednesdayText()); break;
        case 3: weekDay= getFonts().String2Image( language.getThursdayText()); break;
        case 4: weekDay= getFonts().String2Image( language.getFridayText()); break;
        }
        
        g.drawImage(weekDay, 2, 1, Graphics.LEFT | Graphics.TOP );
        g.drawImage(getFonts().String2Image( String.valueOf(m_actual % TimeTable.DAY_LESSONS + 1) ), BLOCK_WIDTH-2, 1, Graphics.RIGHT | Graphics.TOP );
        g.drawRect(0, 0, BLOCK_WIDTH-1, getCaptionHeight() - 1 );
        
        return Image.createImage( returnIm );
    }
   
    
    private int getCaptionHeight(){
    	return getFonts().getTextHeight() + 2;
    }


	private FontManager getFonts() {
		return FontManager.getInstance();
	}


	private static Image getCommentSign() {
		return GraphicManager.getInstance().getCommentSign();
	}
    
}